home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / intuition / icclass.c < prev    next >
C/C++ Source or Header  |  1996-10-29  |  7KB  |  318 lines

  1. /* AROS icclass implementation
  2.  * 10/25/96 caldi@usa.nai.net
  3.  */
  4.  
  5. #include <exec/types.h>
  6.  
  7. #include <dos/dos.h>
  8. #include <dos/dosextens.h>
  9.  
  10. #include <intuition/intuition.h>
  11. #include <intuition/intuitionbase.h>
  12. #include <intuition/classes.h>
  13. #include <intuition/classusr.h>
  14. #include <intuition/gadgetclass.h>
  15. #include <intuition/cghooks.h>
  16. #include <intuition/icclass.h>
  17.  
  18. #include <graphics/gfxbase.h>
  19. #include <graphics/gfxmacros.h>
  20.  
  21. #include <utility/tagitem.h>
  22. #include <utility/hooks.h>
  23.  
  24. #include <clib/macros.h>
  25.  
  26. #ifdef _SASC
  27. #include <proto/exec.h>
  28. #include <proto/intuition.h>
  29. #include <proto/graphics.h>
  30. #include <proto/utility.h>
  31. #elif __GNUC__
  32. #include <clib/exec_protos.h>
  33. #include <clib/intuition_protos.h>
  34. #include <clib/graphics_protos.h>
  35. #include <clib/utility_protos.h>
  36. #endif
  37.  
  38. #ifdef _AROS
  39. #include <aros/asmcall.h>
  40. #include <clib/alib_protos.h>
  41. #include "intuition_intern.h"
  42. #endif
  43.  
  44. /****************************************************************************/
  45.  
  46.  
  47. /****************************************************************************/
  48.  
  49. struct ICData
  50. {
  51.     Object       * ic_Target;
  52.     struct TagItem * ic_Mapping;
  53.     struct TagItem * ic_CloneTags;
  54.     ULONG         ic_LoopCounter;
  55. };
  56.  
  57. /****************************************************************************/
  58.  
  59. #undef IntuitionBase
  60. #define IntuitionBase     ((struct IntuitionBase *)(cl->cl_UserData))
  61.  
  62. #ifdef ICTARGET
  63.  
  64. /* This nifty routine (hopefully) allows us to send a IDCMP message from a boopsi gadget method.
  65.  *
  66.  * It does not seem like we can support ICTARGET_IDCMP until AROS has a real compatible intuition :)
  67.  */
  68. static struct IntuiMessage SendIDCMPUpdate( Class *cl, Object *o, struct opUpdate *msg, ULONG Class, UWORD Code, APTR IAddress )
  69. {
  70.     struct IntuiMessage *imsg;
  71.  
  72.     imsg = msg->opu_GInfo->gi_Window->MessageKey;
  73.  
  74.     while( imsg && !(imsg->Class & IDCMP_LONELYMESSAGE) )
  75.     {
  76.     imsg = imsg->SpecialLink;
  77.     }
  78.  
  79.     if( !imsg )
  80.     {
  81.     if( imsg = AllocMem( sizeof( struct ExtIntuiMessage ), MEMF_CLEAR ) )
  82.     {
  83.         imsg->SpecialLink = msg->opu_GInfo->gi_Window->MessageKey;
  84.         msg->opu_GInfo->gi_Window->MessageKey = imsg->SpecialLink;
  85.         imsg->ExecMessage.mn_ReplyPort = msg->opu_GInfo->gi_Window->WindowPort;
  86.     }
  87.     }
  88.  
  89.     if( imsg )
  90.     {
  91.     imsg->Class = Class;
  92.     imsg->Code = Code;
  93.     imsg->Qualifier = 0;
  94.     imsg->IAddress = IAddress;
  95.     imsg->MouseX = 0;
  96.     imsg->MouseY = 0;
  97.     imsg->Seconds = 0;
  98.     imsg->Micros = 0;
  99.     imsg->IDCMPWindow = msg->opu_GInfo->gi_Window;
  100.  
  101.     PutMsg( msg->opu_GInfo->gi_Window->UserPort, (struct Message *)imsg );
  102.     }
  103.     return( imsg );
  104. }
  105. #endif
  106.  
  107.  
  108. /* Send update notification to target
  109.  */
  110. static ULONG notify_icclass(Class *cl, Object *o, struct opUpdate *msg)
  111. {
  112.     struct ICData * ic = INST_DATA(cl,o);
  113.  
  114.     if ( ic->ic_Target != NULL )
  115.     {
  116.     if ( (msg->opu_AttrList) && (msg->opu_GInfo) )
  117.     {
  118.         ic->ic_LoopCounter += 1UL;
  119.  
  120.         /* don't get caught in a circular notify target loop */
  121.         if ( ic->ic_LoopCounter == 1UL)
  122.         {
  123.         if (ic->ic_Target != (Object *)ICTARGET_IDCMP)
  124.         {
  125.             if ((ic->ic_CloneTags = CloneTagItems(msg->opu_AttrList)))
  126.             {
  127.             if (ic->ic_Mapping != NULL)
  128.             {
  129.                 MapTags(ic->ic_CloneTags, ic->ic_Mapping, TRUE);
  130.             }
  131.  
  132.             DoMethod( ic->ic_Target,
  133.                 OM_UPDATE,
  134.                 ic->ic_CloneTags,
  135.                 msg->opu_GInfo,
  136.                 msg->opu_Flags);
  137.  
  138.             FreeTagItems(ic->ic_CloneTags);
  139.             }
  140.         }
  141. #ifdef ICTARGET
  142.         else
  143.         {
  144.             if ( ic->ic_CloneTags = CloneTagItems(msg->opu_AttrList) )
  145.             {
  146.             if (ic->ic_Mapping != NULL)
  147.             {
  148.                 MapTags(ic->ic_CloneTags, ic->ic_Mapping, TRUE);
  149.             }
  150.  
  151.             SendIDCMPUpdate( cl, o, msg, IDCMP_IDCMPUPDATE, 0, ic->ic_CloneTags);
  152.  
  153.             /* NOTE: ReplyMsg() must cause FreeTagItems(imsg->IAddress)
  154.              * when freeing a  IDCMP_IDCMPUPDATE message!!
  155.              */
  156.             }
  157.         }
  158. #endif
  159.         }
  160.  
  161.         ic->ic_LoopCounter -= 1UL;
  162.     }
  163.     }
  164.     return(1UL);
  165. }
  166.  
  167. /* icclass boopsi dispatcher
  168.  */
  169. AROS_UFH3(static IPTR, dispatch_icclass,
  170.     AROS_UFHA(Class *,  cl,  A0),
  171.     AROS_UFHA(Object *, o,   A2),
  172.     AROS_UFHA(Msg,      msg, A1)
  173. )
  174. {
  175.     IPTR retval = 0UL;
  176.     struct ICData *ic;
  177.  
  178.     if (msg->MethodID != OM_NEW)
  179.     ic = INST_DATA(cl, retval);
  180.  
  181.     switch(msg->MethodID)
  182.     {
  183.     case OM_NEW:
  184.     retval = DoSuperMethodA(cl, o, msg);
  185.  
  186.     if (!retval)
  187.         break;
  188.  
  189.     ic = INST_DATA(cl, retval);
  190.  
  191.     /* set some defaults */
  192.     ic->ic_Target     = NULL;
  193.     ic->ic_Mapping     = NULL;
  194.     ic->ic_CloneTags = NULL;
  195.  
  196.     /* Handle our special tags - overrides defaults */
  197.     /* set_icclass(cl, (Object*)retval, (struct opSet *)msg); */
  198.  
  199.     /* Fall through */
  200.  
  201.     case OM_SET:
  202.     {
  203.         struct TagItem *tstate = ((struct opSet *)msg)->ops_AttrList;
  204.         struct TagItem *tag;
  205.  
  206.         while ((tag = NextTagItem(&tstate)))
  207.         {
  208.         switch(tag->ti_Tag)
  209.         {
  210.         case ICA_MAP:
  211.             ic->ic_Mapping = (struct TagItem *)tag->ti_Data;
  212.             break;
  213.  
  214.         case ICA_TARGET:
  215.             ic->ic_Target = (Object *)tag->ti_Data;
  216.             break;
  217.         }
  218.         }
  219.     }
  220.     break;
  221.  
  222.     case OM_NOTIFY:
  223.     retval = (IPTR)notify_icclass(cl, o, (struct opUpdate *)msg);
  224.     break;
  225.  
  226.     case OM_DISPOSE:
  227.     {
  228.         struct ICData *ic = INST_DATA(cl, o);
  229.  
  230.         ic->ic_LoopCounter = 0UL;
  231.  
  232.         if(ic->ic_CloneTags)
  233.         {
  234.         FreeTagItems(ic->ic_CloneTags);
  235.         ic->ic_CloneTags = NULL;
  236.         }
  237.     }
  238.  
  239.     break;
  240.  
  241.     case OM_GET:
  242.     switch (((struct opGet *)msg)->opg_AttrID)
  243.     {
  244.     case ICA_MAP:
  245.         *((struct opGet *)msg)->opg_Storage = (ULONG)ic->ic_Mapping;
  246.         break;
  247.  
  248.     case ICA_TARGET:
  249.         *((struct opGet *)msg)->opg_Storage = (ULONG)ic->ic_Target;
  250.         break;
  251.     }
  252.  
  253.     break;
  254.  
  255.     /*
  256.     NOTE: I current don't see the purpose of the ICM_* methods
  257.     this implementation could be WAY off base...
  258.     */
  259.  
  260.     case  ICM_SETLOOP:          /* set/increment loop counter    */
  261.     {
  262.         struct ICData *ic = INST_DATA(cl, o);
  263.  
  264.         ic->ic_LoopCounter += 1UL;
  265.     }
  266.  
  267.     break;
  268.  
  269.     case  ICM_CLEARLOOP:    /* clear/decrement loop counter */
  270.     {
  271.         struct ICData *ic = INST_DATA(cl, o);
  272.  
  273.         ic->ic_LoopCounter -= 1UL;
  274.     }
  275.  
  276.     break;
  277.  
  278.     case  ICM_CHECKLOOP:    /* set/increment loop     */
  279.     {
  280.         struct ICData *ic = INST_DATA(cl, o);
  281.  
  282.         retval = (IPTR)ic->ic_LoopCounter;
  283.     }
  284.  
  285.     break;
  286.  
  287.     default:
  288.     retval = DoSuperMethodA(cl, o, msg);
  289.     break;
  290.     } /* switch */
  291.  
  292.     return retval;
  293. }  /* dispatch_icclass */
  294.  
  295. #undef IntuitionBase
  296.  
  297. /****************************************************************************/
  298.  
  299. /* Initialize our image class. */
  300. struct IClass *InitICClass (struct IntuitionBase * IntuitionBase)
  301. {
  302.     struct IClass *cl = NULL;
  303.  
  304.     /* This is the code to make the icclass...
  305.     */
  306.     if ( (cl = MakeClass(ICCLASS, ROOTCLASS, NULL, sizeof(struct ICData), 0)) )
  307.     {
  308.     cl->cl_Dispatcher.h_Entry    = (APTR)AROS_ASMFUNC_NAME(dispatch_icclass);
  309.     cl->cl_Dispatcher.h_SubEntry = NULL;
  310.     cl->cl_UserData          = (IPTR)IntuitionBase;
  311.  
  312.     AddClass (cl);
  313.     }
  314.  
  315.     return (cl);
  316. }
  317.  
  318.